/**
 * @brief 一个简单的通用策略模式
 * @version 1.0
 * @author 宋炜
 * @date 2024-4-23
 */

class strategy
{
        constructor()
        {
                this.m_funcs__ = new Map();
        }

        /**
         * @brief 添加方法。
         * @param {*} key，方法索引
         * @param {*} func ， 可以使用任意个参数
         */
        add( key , func ){
                if( typeof( func ) != 'function' ){
                        throw '参数func必须是函数'
                }

                if( this.m_funcs__.has( key ) ){
                        throw `${key} 已经存在`
                }
                this.m_funcs__.set( key , func );
        }
        /**
         * 移除函数
         * @param {*} key 
         */
        remove( key ){
                if( this.m_funcs__.has( key )){
                        this.m_funcs__.delete( key );
                }
        }
        /**
         * 调用函数。
         * @param {*} key,函数索引
         * @param {*} params， 函数的参数表
         * @return 返回被调用函数的返回值
         */
        call( key , ...params )
        {
                if( this.m_funcs__.has( key )){
                        let func = this.m_funcs__.get( key );
                        return func( ...params );
                }

                return null;
        }

        /**
         * 使用promise的方法调用函数
         * @param {*} key 
         * @param  {...any} params 
         * @returns 
         */
        callAsync( key , ...params )
        {
                return new Promise(( res , rej )=>{
                        try{
                                if( this.m_funcs__.has( key )){
                                        let func = this.m_funcs__.get( key );
                                        let rst = func( ...params );

                                        res( rst );
                                }
                                rej( '方法不存在' )
                        }catch( e ){
                                rej( e );
                        }
                });
        }
}

module.exports = strategy;